#ifndef REFACTOR_H
#define REFACTOR_H

#include "isop.h"
#include "info/cktinfo.h"

struct Cube
{
   Cube(){}
   Cube( unsigned s , unsigned * d ):size(s),data(d){}
   unsigned   size;
   unsigned * data;
   inline unsigned operator[]( unsigned i )const{return data[i];}
   inline unsigned & operator[]( unsigned i ){return data[i];}
   inline bool empty()const{return size == 0 ;}
};
typedef Cube cube_t;

class Refactor : public CktInfo , ISOP
{  
   // node traversing 
   vec<unsigned>    _cone;
   vec<unsigned>    _build_cone;
   unsigned         _cut[ RF_CUT_LIMIT + 1 ];
   unsigned         _cutSize;

   vec<bool_t>      _tables;
   vec<uint64_t * >   _truth_table_pages; // really data pool
   void table_allocate( unsigned n );

   // truth table 
   unsigned         _fun_length;
   vec<ushort>      _funmap;            // simulation usage

   private:

   unsigned * _mem_start;
   unsigned * _mem;
   unsigned   _size;

   AigLit qfactor( cube_t );
   cube_t divide( cube_t , unsigned );
   cube_t divide( cube_t f , cube_t q , cube_t & d );
   cube_t divide( cube_t f , cube_t q );
   cube_t divide_rem( cube_t & f , unsigned n );
   cube_t quick_divisor( cube_t );
   AigLit ab_c( AigLit a , AigLit b , AigLit c );
   AigLit construct(cube_t);
   AigLit construct(unsigned);
   AigLit lf( cube_t , unsigned c );

   private:

   unsigned rf_get_cut( unsigned idx );
   unsigned rf_count_cost( unsigned cost );
   void resume();
   void build_cone();

   inline cube_t allocate_cube( unsigned k ){ cube_t c( k , _mem ); _mem+=(k); return c ;}
   void     rf_simulate( );  
   //AigLit   factorize( sop_t );

   bool check_isop();

   public:

   Refactor( );
   ~Refactor();

   void init();
   void run( unsigned i );
   void run();
   
   inline bool_t getfun( unsigned idx ) const { return _tables[ _funmap[ idx] ]; } 
   void inv_fun(unsigned idx );

   bool      INV;
};

#endif
